package com.lxw.report.meta.controller.handler;

/**
 * 全局异常处理器
 *
 * @author lxw
 */

import com.lxw.report.meta.Exception.CommonException;
import com.lxw.report.meta.vo.ResultVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * 全局异常处理
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理@Validated参数校验失败异常
     * @param exception 异常类
     * @return 响应
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultVo validatedHandler(MethodArgumentNotValidException exception){
        logger.error(exception.getMessage(),exception);
        BindingResult result = exception.getBindingResult();
        List<ObjectError> errors = result.getAllErrors();
        return ResultVo.fail(errors.get(0).getDefaultMessage(),this.getFirstExceptionMessage(exception));
    }

    /**
     * 处理通用业务异常
     * @param exception        exception
     * @return 响应结果
     */
    @ExceptionHandler(CommonException.class)
    public ResultVo customExceptionHandler(CommonException exception) {
        logger.error(exception.getMessage(),exception);
        return ResultVo.fail(exception.getMessage(),this.getFirstExceptionMessage(exception));
    }

    /**
     * 处理其他
     * @param throwable        exception
     * @return 响应结果
     */
    @ExceptionHandler(Throwable.class)
    public ResultVo runtimeExceptionHandler(Throwable throwable) {
        logger.error(throwable.getMessage(),throwable);
        return ResultVo.fail(throwable.getMessage(),this.getFirstExceptionMessage(throwable));
    }

    private String getFirstExceptionMessage(Throwable e){
        StackTraceElement[] stackTraceArr = e.getStackTrace();
        String position="";
        if(stackTraceArr.length>0){
            StackTraceElement stackTrace=stackTraceArr[0];
            position=stackTrace.toString();
        }
        return position;
    }
}
